<html>
<head><title>Plug-in registry resolution</title></head>
<body>
<h1>Plug-in registry resolution</h1>
<EM>Last update: April 23, 2003</EM> 
<p><cite>This document is intended as a home for gathering as much information 
  about the expected semantics for the registry resolution algorithm as possible. 
  The goal is to keep this knowledge separately from the implementation (which 
  may tell a different story), in order to make easier for developers to enhance/fix 
  it or to develop a new algorithm for registry resolution. Comments and improvements 
  are welcome. </cite></p>
<h3>Soft pre-requisites</h3>

<p>Soft pre-requisites are pre-requisites whose &quot;optional&quot; clause is 
  &quot;true&quot;. </p>

<p>Unsatisfied optional pre-requisites should be ignored (handled in the 
same way as if they didn't exist at all).</p>

<p>An optional pre-requisite will be ignored if any of the following 
conditions apply:</p>
<ul>
	<li>the required plug-in does not exist at all;</li>
	<li>the required plug-in does exist but there are no versions 
	compatible with the required version;</li>
	<li>the required plug-in exists and there is a version compatible 
	with the required version but the addition of this plug-in would cause 
	a conflict.  A conflict arises if more than one version 
	of a given plug-in are required by other plug-ins, the versions are not compatible 
	with each other, and at least one of the versions is not a library 
	plug-in.</li>
</ul>

<p>If an optional pre-requisite is ignored for any of the reasons listed above no 
error message is generated (but an informational message may be output to 
indicate that this pre-requisite is being ignored).  Ignoring an optional 
pre-requisite does not cause any plug-ins to be disabled.  This causes 
potential error conditions to be more complex.  Each time we have a situation 
where we have a conflict, we must first check to see if this is an optional 
pre-requisite.</p>

<h3>Version matching</h3>

<p> The following applies for both plug-in pre-requisites and fragments matching their associated plug-ins.</p>

<p>Versions have the following form: major.minor.service.qualifier, where major, minor and service 
are integers and qualifier is a string.</p>

<p>Version Numbers are matched as follows:</p><ul>
	<li>if no version number is specified, pick the latest version that 
	satisfies any other related constraints (which is not necessarily 
	the latest one available in the registry);</li>
	<li>perfect Version (a.b.c.q is a perfect match with d.e.f.r) if:
	 <p>a = d and b = e and c = f and q = r</p>
	</li>
	<li>equivalent Version (a.b.c.q is an equivalent match with d.e.f.r) if: 
	<p>a = d and b = e and ((c &gt; f) or (c = f and q &gt;= r))</p>
	</li>
	<li>compatible Version (a.b.c.q is compatible with d.e.f.r) if: 
	<p>a = d and ((b &gt; e) or (b = e and c &gt; f) or (b = e and c = f and q &gt;= r)) </p>
	</li>
	<li>greaterOrEqual Version (a.b.c.q is a higher version than d.e.f.r) if: 
	<p>a &gt; d or (a = d and b &gt; e) or (a = d and b = e and c &gt; f) or (a = d and b = e and c = f and q &gt;= r)</p>
	</li>
</ul>

<p>Also:</p>

<p>Two or more versions of the same plug-in can only be simultaneously 
enabled if they all are <cite>library plug-ins</cite> (they do not expose extension 
points nor contribute extensions).</p>

<p>If a highest version of a plug-in is disabled for some reason, the new highest 
  version (if available) should replace it (when possible) - all plug-ins (not 
  fragments) that required the disabled version should refer to the new one. </p>
<h3>Questions to be answered</h3>

<ol>
  <li>What happens if a fragment contributes pre-requisites to a plug-in that 
    has multiple versions, and these pre-requisites cannot be satisfied? Currently, 
    the association of a fragment and a plug-in happens before the resolution 
    itself starts. So if a plug-in a fragment contributes to is disabled, the 
    fragment is lost (we don't try the next highest version). Should we? This 
    would cause all versions compatible with the fragment to be successively disabled, 
    if the fragment contributes unsatisfiable pre-requisites. Do we want that?</li>
</ol>

<h3>Current registry resolution algorithm (RegistryResolver#resolve)</h3>

<p>The existing resolution algorithm works based on a directed graph whose nodes 
  represent all versions of a given plug-in, and arc from &quot;a&quot; to &quot;b&quot; 
  means plug-in &quot;a&quot; requires plug-in &quot;b&quot;. The algorithm starting 
  point is a set of root vertices (in-degree is 0) - plug-ins that are not required 
  by any other plug-ins. The resolution is done through a depth-first traversal 
  of the graph from the roots to their pre-requisites.</p>

<ol>
<li>Initial state: Registry initially contains all plug-ins and fragments 
discovered by the platform - no checking of pre-requisites has been done.</li>
<li>Model objects that are missing mandatory fields are ignored (#required*)</li>
<li>Create a map of plug-in descriptors where for each plug-in id there is a list 
of plug-in descriptors that have the same id, ordered by plug-in version, higher to lower (#add)</li>
<li>For each fragment in the registry, add it to the list of fragments of the right plug-in descriptor 
(the highest version that fits the matching criteria) (#linkFragments).</li>
<li>For each plug-in which has a fragment:<ul>
	<li>For each fragment in the plug-in's fragment list (the highest 
	version only), add extensions, extension points, libraries and 
	pre-requisites to the plug-in (#resolvePluginFragments).</li>
</ul></li>
<li>Create a set with the identifiers of all root plug-ins in the registry.</li>
<li>If there are no roots, there is circularity - all plug-ins are disabled and 
the process is finished (registry is emptied if it was to be trimmed).</li>
<li>For each plug-in identifier in the current set of roots:<ul>
	<li>Look for the right version(s) to enable, doing a depth-first 
	traversal in its children (plug-ins that require it). This includes 
	ensuring:	<ul>
		<li>all mandatory pre-requisites are satisfied 
		(considering versions and match clauses);</li>
		<li>there are no conflicts (no different versions are 
		required simultaneously of plug-ins that provide 
		extensions/extension points).</li>
		<li>if a root is disabled, its direct children are promoted
		to roots if they are not required by any other plug-ins.</li>
	</ul></li>
</ul></li>
<li>If the registry is to be trimmed, delete any plug-ins which 
are not enabled/do not have pre-requisites satisfied  
(#resolvePluginRegistry).</li>
<li>If the registry is to be linked, link extensions to the targetted extension 
points (#resolvePluginRegistry).</li>
</ol>

<h3>Problems in the current registry resolution algorithm</h3>

<ol>
  <li>all versions of a plug-in are disabled when the version in use causes a 
    conflict - when a plug-in is disabled for causing a conflict, if there are 
    different versions available, the highest one should be selected and the resolution 
    should try to enable that one;</li>
  <li>order should not matter - for instance, when a conflict is detected, all 
    plug-ins involved should be disabled not only the one that introduced the 
    conflict (bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34752">34752</a>);</li>
  <li>fragments not associated with a plug-in or fragments not used because another 
    version of the same fragment exists should be trimmed when the user requests 
    it and currently are not (bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33911">33911</a>).</li>
  <li>the resulting plug-in descriptor should indicate which portions came from 
    fragments (feature request <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23165">23165</a>).</li>
</ol>
</body>
</html>